package com.nnnu.wsnackshop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nnnu.wsnackshop.exception.ObjectException;
import com.nnnu.wsnackshop.mapper.*;
import com.nnnu.wsnackshop.pojo.dto.RiderDTO;
import com.nnnu.wsnackshop.pojo.dto.RiderLoginDTO;
import com.nnnu.wsnackshop.pojo.entity.Deliveries;
import com.nnnu.wsnackshop.pojo.entity.Orders;
import com.nnnu.wsnackshop.pojo.entity.Riders;
import com.nnnu.wsnackshop.pojo.entity.Stores;
import com.nnnu.wsnackshop.pojo.entity.StoreAddresses;
import com.nnnu.wsnackshop.pojo.entity.Addresses;
import com.nnnu.wsnackshop.pojo.vo.RiderStatsVO;
import com.nnnu.wsnackshop.pojo.vo.RiderVO;
import com.nnnu.wsnackshop.result.PageResult;
import com.nnnu.wsnackshop.service.IRidersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nnnu.wsnackshop.utils.JwtUtil;
import com.nnnu.wsnackshop.utils.PasswordUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.math.BigDecimal;

/**
 * <p>
 * 骑手表 服务实现类
 * </p>
 *
 * @author zk
 * @since 2025-05-14
 */
@Service
@Slf4j
public class RidersServiceImpl extends ServiceImpl<RidersMapper, Riders> implements IRidersService {

    private final OrdersMapper ordersMapper;
    private final DeliveriesMapper deliveriesMapper;
    private final StoresMapper storesMapper;
    private final StoreAddressesMapper storeAddressesMapper;
    private final AddressesMapper addressesMapper;

    @Autowired
    public RidersServiceImpl(OrdersMapper ordersMapper, DeliveriesMapper deliveriesMapper,
                             StoresMapper storesMapper, StoreAddressesMapper storeAddressesMapper,
                             AddressesMapper addressesMapper) {
        this.ordersMapper = ordersMapper;
        this.deliveriesMapper = deliveriesMapper;
        this.storesMapper = storesMapper;
        this.storeAddressesMapper = storeAddressesMapper;
        this.addressesMapper = addressesMapper;
    }

    @Override
    public String login(RiderLoginDTO loginDTO) {
        log.info("骑手登录: phone={}", loginDTO.getPhone());

        // 根据手机号查询骑手信息
        LambdaQueryWrapper<Riders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Riders::getPhone, loginDTO.getPhone());
        Riders rider = baseMapper.selectOne(queryWrapper);

        if (rider == null) {
            throw new AuthenticationException("手机号或密码错误");
        }

        // 验证密码
        if (!PasswordUtil.verify(loginDTO.getPassword(), rider.getPassword())) {
            log.error("骑手密码错误: phone={}", loginDTO.getPhone());
            throw new AuthenticationException("手机号或密码错误");
        }

        // 更新骑手状态为在线
        rider.setStatus(1); // 1=在线可接单
        baseMapper.updateById(rider);

        // 生成JWT令牌
        String token = JwtUtil.createTokenWithRider(rider);
        log.info("骑手登录成功: phone={}, riderId={}", loginDTO.getPhone(), rider.getId());

        return token;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer autoAssignRider(Long orderId, Integer storeId) {
        log.info("开始自动分配骑手: orderId={}, storeId={}", orderId, storeId);

        // 1. 查询订单，确认订单状态
        Orders order = ordersMapper.selectById(orderId);
        if (order == null) {
            throw new ObjectException("订单不存在");
        }

        // 2. 确认订单支付状态
        if (order.getPayStatus() != 1) {
            log.error("订单未支付，无法分配骑手: orderId={}, payStatus={}", orderId, order.getPayStatus());
            throw new ObjectException("订单未支付，无法分配骑手");
        }

        // 3. 确认订单状态
        if (order.getOrderStatus() > 2) {
            log.error("订单状态不允许分配骑手: orderId={}, orderStatus={}", orderId, order.getOrderStatus());
            throw new ObjectException("订单已发货或已完成，不能重复分配骑手");
        }

        // 4. 确认配送方式为同城配送
        if (!"local".equals(order.getDeliveryType())) {
            log.error("订单配送方式不是同城配送，无法分配骑手: orderId={}, deliveryType={}", orderId, order.getDeliveryType());
            throw new ObjectException("只有同城配送订单才能分配骑手");
        }

        // 检查是否已存在配送记录
        LambdaQueryWrapper<Deliveries> existingDeliveryQuery = new LambdaQueryWrapper<>();
        existingDeliveryQuery.eq(Deliveries::getOrderId, orderId);
        Deliveries existingDelivery = deliveriesMapper.selectOne(existingDeliveryQuery);

        // 如果已存在配送记录，记录日志
        if (existingDelivery != null) {
            log.info("订单已存在配送记录，将更新而不是创建新记录: orderId={}, deliveryId={}", orderId, existingDelivery.getId());
        }

        // 5. 查询可用骑手（状态为可用且未达到10单上限的骑手）
        List<Riders> availableRiders = getAvailableRiders();

        if (availableRiders.isEmpty()) {
            log.warn("没有可用骑手，创建/更新为待分配配送记录: orderId={}", orderId);

            if (existingDelivery != null) {
                // 更新现有配送记录
                existingDelivery.setRiderId(-1); // 使用-1表示待分配
                existingDelivery.setStatus(0); // 待分配
                existingDelivery.setAssignedAt(LocalDateTime.now());
                existingDelivery.setEstimatedArrivalTime(LocalDateTime.now().plusMinutes(30));
                deliveriesMapper.updateById(existingDelivery);
                log.info("更新现有配送记录为待分配状态: deliveryId={}", existingDelivery.getId());
            } else {
                // 再次检查是否已存在配送记录，避免并发问题
                existingDelivery = deliveriesMapper.selectOne(existingDeliveryQuery);

                if (existingDelivery != null) {
                    // 更新现有配送记录
                    existingDelivery.setRiderId(-1); // 使用-1表示待分配
                    existingDelivery.setStatus(0); // 待分配
                    existingDelivery.setAssignedAt(LocalDateTime.now());
                    existingDelivery.setEstimatedArrivalTime(LocalDateTime.now().plusMinutes(30));
                    deliveriesMapper.updateById(existingDelivery);
                    log.info("并发检测：更新现有配送记录为待分配状态: deliveryId={}", existingDelivery.getId());
                } else {
                    // 创建配送记录，但不分配骑手
                    Deliveries delivery = new Deliveries();
                    delivery.setOrderId(orderId);
                    delivery.setRiderId(-1); // 使用-1表示待分配
                    delivery.setAssignedAt(LocalDateTime.now());
                    delivery.setStatus(0); // 待分配
                    delivery.setDeliveryType("local"); // 同城配送
                    delivery.setEstimatedArrivalTime(LocalDateTime.now().plusMinutes(30));
                    deliveriesMapper.insert(delivery);
                    log.info("创建新的待分配配送记录: orderId={}", orderId);
                }
            }

            // 更新订单状态为配送中，等待骑手分配
            order.setOrderStatus(3); // 配送中
            order.setUpdatedAt(LocalDateTime.now());
            ordersMapper.updateById(order);

            return null;
        }

        // 6. 简单分配算法：选择订单数量最少的骑手
        Riders selectedRider = b(availableRiders);


        // 8. 创建或更新配送记录
        if (existingDelivery != null) {
            // 更新现有配送记录
            a(existingDelivery, selectedRider);
            log.info("更新现有配送记录: deliveryId={}, riderId={}", existingDelivery.getId(), selectedRider.getId());
        } else {
            // 再次检查是否已存在配送记录，避免并发问题
            existingDelivery = deliveriesMapper.selectOne(existingDeliveryQuery);

            if (existingDelivery != null) {
                // 更新现有配送记录
                a(existingDelivery, selectedRider);
                log.info("并发检测：更新现有配送记录: deliveryId={}, riderId={}", existingDelivery.getId(), selectedRider.getId());
            } else {
                // 创建新地配送记录
                Deliveries delivery = new Deliveries();
                delivery.setOrderId(orderId);
                delivery.setRiderId(selectedRider.getId());
                delivery.setAssignedAt(LocalDateTime.now());
                delivery.setStatus(0); // 待接单
                delivery.setDeliveryType("local"); // 同城配送
                delivery.setRiderPhone(selectedRider.getPhone());
                delivery.setEstimatedArrivalTime(LocalDateTime.now().plusMinutes(30));
                deliveriesMapper.insert(delivery);
                log.info("创建新的配送记录: orderId={}, riderId={}", orderId, selectedRider.getId());
            }
        }

        // 9. 更新订单状态
        order.setOrderStatus(3); // 配送中
        order.setUpdatedAt(LocalDateTime.now());
        ordersMapper.updateById(order);

        log.info("骑手分配成功: orderId={}, riderId={}", orderId, selectedRider.getId());

        return selectedRider.getId();
    }

    /**
     * 获取可用骑手列表（状态为可用且未达到10单上限）
     *
     * @return 可用骑手列表
     */
    private List<Riders> getAvailableRiders() {
        List<Riders> availableRiders = new ArrayList<>();
        List<Riders> allOnlineRiders = baseMapper.selectList(
                new LambdaQueryWrapper<Riders>()
                        .in(Riders::getStatus, Arrays.asList(1, 2)) // 状态为可用或忙碌（但可能未达到10单）
        );

        // 检查每个骑手当前正在配送的订单数量
        for (Riders rider : allOnlineRiders) {
            LambdaQueryWrapper<Deliveries> countQuery = new LambdaQueryWrapper<>();
            countQuery.eq(Deliveries::getRiderId, rider.getId())
                    .in(Deliveries::getStatus, Arrays.asList(0, 1)); // 待接单或配送中

            long orderCount = deliveriesMapper.selectCount(countQuery);

            // 如果骑手当前订单数小于10，则可以分配新订单
            if (orderCount < 10) {
                availableRiders.add(rider);
            }
        }

        return availableRiders;
    }

    private void a(Deliveries existingDelivery, Riders selectedRider) {
        existingDelivery.setRiderId(selectedRider.getId());
        existingDelivery.setAssignedAt(LocalDateTime.now());
        existingDelivery.setStatus(0); // 待接单
        existingDelivery.setDeliveryType("local"); // 同城配送
        existingDelivery.setRiderPhone(selectedRider.getPhone());
        existingDelivery.setEstimatedArrivalTime(LocalDateTime.now().plusMinutes(30));
        deliveriesMapper.updateById(existingDelivery);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean acceptOrder(Integer riderId, Long orderId) {
        log.info("骑手接单: riderId={}, orderId={}", riderId, orderId);

        // 1. 查询骑手
        Riders rider = getById(riderId);
        if (rider == null) {
            throw new ObjectException("骑手不存在");
        }

        // 2. 查询订单
        Orders order = ordersMapper.selectById(orderId);
        if (order == null) {
            throw new ObjectException("订单不存在");
        }

        // 3. 查询配送记录
        LambdaQueryWrapper<Deliveries> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Deliveries::getOrderId, orderId);

        // 修改：使用selectList代替selectOne，处理可能有多条记录的情况
        List<Deliveries> deliveryList = deliveriesMapper.selectList(queryWrapper);

        if (deliveryList == null || deliveryList.isEmpty()) {
            log.error("配送记录不存在: orderId={}", orderId);
            throw new ObjectException("配送记录不存在");
        }

        // 使用第一条记录，并记录警告日志如果存在多条记录
        Deliveries delivery = deliveryList.get(0);
        if (deliveryList.size() > 1) {
            log.warn("发现订单存在多条配送记录({}条)，使用第一条: orderId={}, deliveryId={}",
                    deliveryList.size(), orderId, delivery.getId());

            // 可选：删除多余的记录
            for (int i = 1; i < deliveryList.size(); i++) {
                Deliveries extraDelivery = deliveryList.get(i);
                log.warn("删除多余的配送记录: deliveryId={}, orderId={}", extraDelivery.getId(), orderId);
                deliveriesMapper.deleteById(extraDelivery.getId());
            }
        }

        // 4. 检查是否已经被分配给其他骑手
        if (delivery.getRiderId() != null && delivery.getRiderId() > 0 && !delivery.getRiderId().equals(riderId)) {
            log.error("订单已分配给其他骑手: orderId={}, currentRiderId={}, newRiderId={}",
                    orderId, delivery.getRiderId(), riderId);
            throw new ObjectException("订单已分配给其他骑手");
        }

        // 5. 更新配送记录
        delivery.setRiderId(riderId);
        delivery.setStatus(1); // 1=配送中
        delivery.setAssignedAt(LocalDateTime.now());
        delivery.setRiderPhone(rider.getPhone());
        int result = deliveriesMapper.updateById(delivery);

        if (result <= 0) {
            log.error("更新配送记录失败: orderId={}, riderId={}", orderId, riderId);
            throw new ObjectException("更新配送记录失败");
        }

        // 6. 更新订单状态
        order.setOrderStatus(3); // 配送中
        order.setUpdatedAt(LocalDateTime.now());
        ordersMapper.updateById(order);

        log.info("骑手接单成功: riderId={}, orderId={}", riderId, orderId);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean confirmDelivery(Integer riderId, Long orderId) {
        log.info("骑手确认送达: riderId={}, orderId={}", riderId, orderId);

        // 1. 查询配送记录
        LambdaQueryWrapper<Deliveries> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Deliveries::getOrderId, orderId)
                .eq(Deliveries::getRiderId, riderId);

        Deliveries delivery = deliveriesMapper.selectOne(queryWrapper);

        if (delivery == null) {
            log.error("配送记录不存在: riderId={}, orderId={}", riderId, orderId);
            throw new ObjectException("配送记录不存在");
        }

        // 2. 检查配送状态
        if (delivery.getStatus() != 1) {
            log.error("配送状态不允许确认送达: riderId={}, orderId={}, status={}", riderId, orderId, delivery.getStatus());
            throw new ObjectException("当前状态不允许确认送达");
        }

        // 3. 更新配送状态
        delivery.setStatus(2); // 已送达
        delivery.setDeliveredAt(LocalDateTime.now());
        deliveriesMapper.updateById(delivery);

        // 4. 更新订单状态
        Orders order = ordersMapper.selectById(orderId);
        if (order != null) {
            order.setOrderStatus(6); // 已送达待确认收货
            order.setUpdatedAt(LocalDateTime.now());
            ordersMapper.updateById(order);
        }

        // 5. 检查骑手当前订单数并更新骑手状态
        Riders rider = getById(riderId);
        if (rider != null) {
            // 检查骑手是否还有其他正在配送的订单
            LambdaQueryWrapper<Deliveries> riderDeliveriesQuery = new LambdaQueryWrapper<>();
            riderDeliveriesQuery.eq(Deliveries::getRiderId, riderId)
                    .in(Deliveries::getStatus, Arrays.asList(0, 1)); // 待接单或配送中

            long currentOrderCount = deliveriesMapper.selectCount(riderDeliveriesQuery);

            log.info("骑手当前订单数: riderId={}, orderCount={}", riderId, currentOrderCount);

            // 根据订单数量更新骑手状态
            if (currentOrderCount == 0) {
                // 没有其他配送中的订单，将骑手状态设为可用
                rider.setStatus(1); // 可用
                updateById(rider);
            } else if (currentOrderCount < 10 && rider.getStatus() == 2) {
                // 订单数小于10且当前状态为忙碌，则更新为可用
                rider.setStatus(1); // 可用
                updateById(rider);
                log.info("骑手订单数小于10，状态更新为可用: riderId={}, orderCount={}", riderId, currentOrderCount);
            } else if (currentOrderCount >= 10 && rider.getStatus() != 2) {
                // 订单数大于等于10且当前状态不为忙碌，则更新为忙碌
                rider.setStatus(2); // 忙碌
                updateById(rider);
                log.info("骑手订单数大于等于10，状态更新为忙碌: riderId={}, orderCount={}", riderId, currentOrderCount);
            }
        }

        log.info("骑手确认送达成功: riderId={}, orderId={}", riderId, orderId);

        return true;
    }

    @Override
    public boolean updateRiderStatus(Integer riderId, Integer status) {
        log.info("更新骑手状态: riderId={}, status={}", riderId, status);

        if (status < 0 || status > 2) {
            log.error("无效的骑手状态: riderId={}, status={}", riderId, status);
            throw new ObjectException("无效的骑手状态");
        }

        Riders rider = getById(riderId);
        if (rider == null) {
            throw new ObjectException("骑手不存在");
        }

        // 如果要设置为离线状态，检查是否有正在配送的订单
        if (status == 0) {
            LambdaQueryWrapper<Deliveries> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Deliveries::getRiderId, riderId)
                    .eq(Deliveries::getStatus, 1); // 配送中

            long count = deliveriesMapper.selectCount(queryWrapper);

            if (count > 0) {
                log.error("骑手有正在配送的订单，无法设置为离线状态: riderId={}, deliveryCount={}", riderId, count);
                throw new ObjectException("骑手有正在配送的订单，无法设置为离线状态");
            }
        }

        rider.setStatus(status);
        boolean result = updateById(rider);

        log.info("更新骑手状态结果: riderId={}, status={}, result={}", riderId, status, result);

        return result;
    }

    @Override
    public PageResult<Map<String, Object>> getRiderOrders(Integer riderId, String status, int page, int pageSize) {
        log.info("获取骑手订单列表: riderId={}, status={}, page={}, pageSize={}", riderId, status, page, pageSize);

        // 构建查询条件
        LambdaQueryWrapper<Deliveries> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Deliveries::getRiderId, riderId);

        // 根据状态筛选
        if (status != null) {
            switch (status) {
                case "pending" -> queryWrapper.eq(Deliveries::getStatus, 0); // 待接单
                case "delivering" -> queryWrapper.eq(Deliveries::getStatus, 1); // 配送中
                case "completed" -> queryWrapper.eq(Deliveries::getStatus, 2); // 已送达
            }
        }

        // 按分配时间降序排序
        queryWrapper.orderByDesc(Deliveries::getAssignedAt);

        // 分页查询
        Page<Deliveries> deliveryPage = new Page<>(page, pageSize);
        Page<Deliveries> result = deliveriesMapper.selectPage(deliveryPage, queryWrapper);

        // 构建结果
        List<Map<String, Object>> orderList = new ArrayList<>();

        for (Deliveries delivery : result.getRecords()) {
            Orders order = ordersMapper.selectById(delivery.getOrderId());
            if (order != null) {
                Map<String, Object> orderMap = new HashMap<>();
                orderMap.put("orderId", order.getId());
                orderMap.put("orderNo", order.getOrderNo());
                orderMap.put("deliveryId", delivery.getId());
                orderMap.put("status", delivery.getStatus());
                orderMap.put("assignedAt", delivery.getAssignedAt());
                orderMap.put("pickedUpAt", delivery.getPickedUpAt());
                orderMap.put("deliveredAt", delivery.getDeliveredAt());
                orderMap.put("totalAmount", order.getTotalAmount());
                orderMap.put("addressId", order.getAddressId());

                // 计算配送时间（如果已送达）
                if (delivery.getDeliveredAt() != null && delivery.getPickedUpAt() != null) {
                    long minutes = ChronoUnit.MINUTES.between(delivery.getPickedUpAt(), delivery.getDeliveredAt());
                    orderMap.put("deliveryTime", minutes);
                }

                orderList.add(orderMap);
            }
        }

        // 构建分页结果
        PageResult<Map<String, Object>> pageResult = new PageResult<>();
        pageResult.setTotal(result.getTotal());
        pageResult.setItems(orderList);

        return pageResult;
    }

    @Override
    public RiderVO getRiderDetail(Integer riderId) {
        log.info("获取骑手详情: riderId={}", riderId);

        // 查询骑手基本信息
        Riders rider = getById(riderId);
        if (rider == null) {
            log.error("骑手不存在: {}", riderId);
            throw new ObjectException("骑手不存在");
        }

        // 转换为VO对象
        RiderVO riderVO = c(rider);

        // 查询当前正在配送的订单数
        LambdaQueryWrapper<Deliveries> currentOrderQuery = new LambdaQueryWrapper<>();
        currentOrderQuery.eq(Deliveries::getRiderId, riderId)
                .in(Deliveries::getStatus, Arrays.asList(0, 1)); // 待接单或配送中
        int currentOrderCount = Math.toIntExact(deliveriesMapper.selectCount(currentOrderQuery));
        riderVO.setCurrentOrderCount(currentOrderCount);

        // 查询今日已完成订单数
        LocalDateTime todayStart = LocalDateTime.now().toLocalDate().atStartOfDay();
        LambdaQueryWrapper<Deliveries> completedOrderQuery = new LambdaQueryWrapper<>();
        completedOrderQuery.eq(Deliveries::getRiderId, riderId)
                .eq(Deliveries::getStatus, 2) // 已送达
                .ge(Deliveries::getDeliveredAt, todayStart);
        int completedOrderCount = Math.toIntExact(deliveriesMapper.selectCount(completedOrderQuery));
        riderVO.setCompletedOrderCount(completedOrderCount);

        // 计算平均配送时间（分钟）
        try {
            // 查询最近30天内的已完成配送
            LocalDateTime thirtyDaysAgo = LocalDateTime.now().minusDays(30);
            LambdaQueryWrapper<Deliveries> avgTimeQuery = new LambdaQueryWrapper<>();
            avgTimeQuery.eq(Deliveries::getRiderId, riderId)
                    .eq(Deliveries::getStatus, 2) // 已送达
                    .ge(Deliveries::getDeliveredAt, thirtyDaysAgo)
                    .isNotNull(Deliveries::getPickedUpAt)
                    .isNotNull(Deliveries::getDeliveredAt);

            List<Deliveries> completedDeliveries = deliveriesMapper.selectList(avgTimeQuery);

            if (!completedDeliveries.isEmpty()) {
                long totalMinutes = 0;
                for (Deliveries delivery : completedDeliveries) {
                    // 计算从取货到送达的分钟数
                    long minutes = ChronoUnit.MINUTES.between(delivery.getPickedUpAt(), delivery.getDeliveredAt());
                    totalMinutes += minutes;
                }
                int avgMinutes = (int) (totalMinutes / completedDeliveries.size());
                riderVO.setAvgDeliveryTime(avgMinutes);
            } else {
                riderVO.setAvgDeliveryTime(0);
            }
        } catch (Exception e) {
            log.error("计算平均配送时间出错: {}", e.getMessage(), e);
            riderVO.setAvgDeliveryTime(0);
        }

        return riderVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean manualAssignRider(Long orderId, Integer riderId) {
        log.info("手动分配骑手: orderId={}, riderId={}", orderId, riderId);

        // 1. 查询订单
        Orders order = ordersMapper.selectById(orderId);
        if (order == null) {
            log.error("订单不存在: orderId={}", orderId);
            throw new ObjectException("订单不存在");
        }

        // 2. 查询骑手
        Riders rider = getById(riderId);
        if (rider == null) {
            throw new ObjectException("骑手不存在");
        }

        // 3. 检查骑手状态
        if (rider.getStatus() == 0) {
            log.error("骑手当前处于离线状态，无法分配订单: riderId={}", riderId);
            throw new ObjectException("骑手当前处于离线状态，无法分配订单");
        }

        // 4. 检查骑手当前订单数量
        LambdaQueryWrapper<Deliveries> countQuery = new LambdaQueryWrapper<>();
        countQuery.eq(Deliveries::getRiderId, riderId)
                .in(Deliveries::getStatus, Arrays.asList(0, 1)); // 待接单或配送中

        long currentOrderCount = deliveriesMapper.selectCount(countQuery);

        if (currentOrderCount >= 10) {
            log.error("骑手当前订单数已达上限，无法分配更多订单: riderId={}, orderCount={}", riderId, currentOrderCount);
            throw new ObjectException("骑手当前订单数已达上限，无法分配更多订单");
        }

        // 5. 查询配送记录
        LambdaQueryWrapper<Deliveries> deliveryQuery = new LambdaQueryWrapper<>();
        deliveryQuery.eq(Deliveries::getOrderId, orderId);

        Deliveries delivery = deliveriesMapper.selectOne(deliveryQuery);

        if (delivery == null) {
            // 创建新地配送记录
            delivery = new Deliveries();
            delivery.setOrderId(orderId);
            delivery.setRiderId(riderId);
            delivery.setAssignedAt(LocalDateTime.now());
            delivery.setStatus(0); // 待接单
            delivery.setDeliveryType("local"); // 同城配送

            // 设置骑手电话
            delivery.setRiderPhone(rider.getPhone());

            // 设置预计送达时间（当前时间+30分钟）
            delivery.setEstimatedArrivalTime(LocalDateTime.now().plusMinutes(30));

            deliveriesMapper.insert(delivery);
        } else {
            // 更新现有配送记录
            delivery.setRiderId(riderId);
            delivery.setRiderPhone(rider.getPhone());
            delivery.setAssignedAt(LocalDateTime.now());

            // 如果预计送达时间为空，则设置
            if (delivery.getEstimatedArrivalTime() == null) {
                delivery.setEstimatedArrivalTime(LocalDateTime.now().plusMinutes(30));
            }

            deliveriesMapper.updateById(delivery);
        }

        // 6. 更新骑手状态（如果分配后达到10单，则设为忙碌）
        if (currentOrderCount + 1 >= 10) {
            rider.setStatus(2); // 忙碌
            updateById(rider);
            log.info("骑手状态更新为忙碌: riderId={}", riderId);
        } else if (rider.getStatus() != 1) {
            // 如果当前不是可用状态，但订单数未达到10，则设为可用
            rider.setStatus(1); // 可用
            updateById(rider);
            log.info("骑手状态更新为可用: riderId={}", riderId);
        }

        log.info("手动分配骑手成功: orderId={}, riderId={}", orderId, riderId);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Riders addRider(RiderDTO riderDTO) {
        log.info("添加骑手: {}", riderDTO);

        // 检查手机号是否已存在
        LambdaQueryWrapper<Riders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Riders::getPhone, riderDTO.getPhone());
        if (baseMapper.selectCount(queryWrapper) > 0) {
            log.error("手机号已存在: {}", riderDTO.getPhone());
            throw new ObjectException("手机号已存在");
        }

        // 创建骑手对象
        Riders rider = new Riders();
        rider.setName(riderDTO.getName());
        rider.setPhone(riderDTO.getPhone());
        rider.setVehicleType(riderDTO.getVehicleType());
        rider.setStatus(riderDTO.getStatus() != null ? riderDTO.getStatus() : 0); // 默认离线

        // 设置默认密码（123456）
        rider.setPassword(PasswordUtil.hash("123456"));

        // 设置创建时间
        rider.setCreatedAt(LocalDateTime.now());
        rider.setUpdatedAt(LocalDateTime.now());

        // 保存到数据库
        baseMapper.insert(rider);
        log.info("骑手添加成功: id={}, name={}", rider.getId(), rider.getName());

        return rider;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRider(RiderDTO riderDTO) {
        log.info("更新骑手信息: {}", riderDTO);

        // 检查骑手是否存在
        Riders existingRider = getById(riderDTO.getId());
        if (existingRider == null) {
            throw new ObjectException("骑手不存在");
        }

        // 如果更新手机号，检查新手机号是否已被其他骑手使用
        if (!existingRider.getPhone().equals(riderDTO.getPhone())) {
            LambdaQueryWrapper<Riders> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Riders::getPhone, riderDTO.getPhone())
                    .ne(Riders::getId, riderDTO.getId());
            if (baseMapper.selectCount(queryWrapper) > 0) {
                log.error("手机号已被其他骑手使用: {}", riderDTO.getPhone());
                throw new ObjectException("手机号已被其他骑手使用");
            }
        }

        // 更新骑手信息
        existingRider.setName(riderDTO.getName());
        existingRider.setPhone(riderDTO.getPhone());
        existingRider.setVehicleType(riderDTO.getVehicleType());
        if (riderDTO.getStatus() != null) {
            existingRider.setStatus(riderDTO.getStatus());
        }
        existingRider.setUpdatedAt(LocalDateTime.now());

        // 保存到数据库
        boolean result = updateById(existingRider);
        log.info("骑手信息更新{}: id={}", result ? "成功" : "失败", existingRider.getId());

        return result;
    }

    @Override
    public PageResult<Map<String, Object>> getRiderDeliveryHistory(Integer riderId, String timeRange, int page,
                                                                   int pageSize) {
        log.info("获取骑手配送历史: riderId={}, timeRange={}, page={}, pageSize={}", riderId, timeRange, page, pageSize);

        // 检查骑手是否存在
        if (!baseMapper.exists(new LambdaQueryWrapper<Riders>().eq(Riders::getId, riderId))) {
            throw new ObjectException("骑手不存在");
        }

        // 构建查询条件
        LambdaQueryWrapper<Deliveries> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Deliveries::getRiderId, riderId);

        // 根据时间范围设置查询条件
        LocalDateTime startTime = null;
        switch (timeRange) {
            case "today":
                // 今天
                startTime = LocalDateTime.now().toLocalDate().atStartOfDay();
                break;
            case "week":
                // 本周（过去7天）
                startTime = LocalDateTime.now().minusDays(7);
                break;
            case "month":
                // 本月（过去30天）
                startTime = LocalDateTime.now().minusDays(30);
                break;
            case "all":
            default:
                // 全部，不设置时间限制
                break;
        }

        // 如果有时间范围，添加时间条件
        if (startTime != null) {
            queryWrapper.ge(Deliveries::getAssignedAt, startTime);
        }

        // 按分配时间降序排序
        queryWrapper.orderByDesc(Deliveries::getAssignedAt);

        // 分页查询
        Page<Deliveries> pageResult = new Page<>(page, pageSize);
        Page<Deliveries> deliveriesPage = deliveriesMapper.selectPage(pageResult, queryWrapper);

        // 转换为Map对象列表
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (Deliveries delivery : deliveriesPage.getRecords()) {
            // 查询订单信息
            Orders order = ordersMapper.selectById(delivery.getOrderId());
            if (order == null) {
                continue;
            }

            Map<String, Object> item = new HashMap<>();
            item.put("deliveryId", delivery.getId());
            item.put("orderId", delivery.getOrderId());
            item.put("orderNo", order.getOrderNo());
            item.put("storeId", order.getStoreId());

            // 获取店铺地址信息
            Stores store = storesMapper.selectById(order.getStoreId());
            if (store != null) {
                item.put("storeName", store.getName());
                // 查询店铺地址
                LambdaQueryWrapper<StoreAddresses> storeAddressQueryWrapper = new LambdaQueryWrapper<>();
                storeAddressQueryWrapper.eq(StoreAddresses::getStoreId, store.getId());
                storeAddressQueryWrapper.eq(StoreAddresses::getIsDefault, 1);
                StoreAddresses storeAddress = storeAddressesMapper.selectOne(storeAddressQueryWrapper);
                if (storeAddress != null) {
                    item.put("storeAddress", storeAddress.getDetail());
                } else {
                    item.put("storeAddress", "未知地址");
                }
            } else {
                item.put("storeName", "未知店铺");
                item.put("storeAddress", "未知地址");
            }

            // 获取配送地址
            Addresses customerAddress = addressesMapper.selectById(order.getAddressId());
            if (customerAddress != null) {
                item.put("customerAddress", customerAddress.getDetail());
            } else {
                item.put("customerAddress", order.getDeliveryNotes() != null ? order.getDeliveryNotes() : "未知地址");
            }

            // 设置配送距离（应该是从订单的门店地址到用户地址的距离）
            // 由于距离需要计算，这里先设置一个模拟值，实际应该根据经纬度计算
            double distance = 3.5; // 模拟距离为3.5公里
            item.put("distance", distance);

            item.put("deliveryStatus", delivery.getStatus());

            // 设置配送状态文本
            switch (delivery.getStatus()) {
                case 0:
                    item.put("statusText", "待接单");
                    break;
                case 1:
                    item.put("statusText", "配送中");
                    break;
                case 2:
                    item.put("statusText", "已送达");
                    break;
                case -1:
                    item.put("statusText", "已取消");
                    break;
                default:
                    item.put("statusText", "未知");
            }

            // 设置时间信息
            item.put("assignedAt", delivery.getAssignedAt());
            item.put("pickedUpAt", delivery.getPickedUpAt());
            item.put("deliveredAt", delivery.getDeliveredAt());
            item.put("startTime", delivery.getPickedUpAt()); // 开始时间就是取货时间
            item.put("endTime", delivery.getDeliveredAt()); // 结束时间就是送达时间

            // 计算配送耗时（分钟）
            if (delivery.getStatus() == 2 && delivery.getPickedUpAt() != null && delivery.getDeliveredAt() != null) {
                long minutes = ChronoUnit.MINUTES.between(delivery.getPickedUpAt(), delivery.getDeliveredAt());
                item.put("deliveryTime", minutes);
                item.put("duration", minutes); // 添加duration字段与前端对应
            } else {
                item.put("deliveryTime", null);
                item.put("duration", null);
            }

            // 设置订单金额
            item.put("orderAmount", order.getTotalAmount());

            // 设置评分信息
            if (delivery.getDeliveryRating() != null) {
                item.put("rating", delivery.getDeliveryRating());
            } else {
                item.put("rating", 0);
            }

            resultList.add(item);
        }

        // 返回分页结果
        return new PageResult<Map<String, Object>>().setTotal(deliveriesPage.getTotal()).setItems(resultList);
    }

    @Override
    public RiderStatsVO getRiderStats(Integer riderId) {
        log.info("获取骑手统计数据: riderId={}", riderId);

        // 检查骑手是否存在
        Riders rider = getById(riderId);
        if (rider == null) {
            throw new ObjectException("骑手不存在");
        }

        RiderStatsVO statsVO = new RiderStatsVO();
        statsVO.setId(riderId);

        // 获取今日数据
        LocalDateTime todayStart = LocalDateTime.now().toLocalDate().atStartOfDay();

        // 今日订单数
        LambdaQueryWrapper<Deliveries> todayOrdersQuery = new LambdaQueryWrapper<>();
        todayOrdersQuery.eq(Deliveries::getRiderId, riderId)
                .ge(Deliveries::getAssignedAt, todayStart);
        int todayOrders = Math.toIntExact(deliveriesMapper.selectCount(todayOrdersQuery));
        statsVO.setTodayOrderCount(todayOrders);

        // 今日已完成订单数
        LambdaQueryWrapper<Deliveries> todayCompletedQuery = new LambdaQueryWrapper<>();
        todayCompletedQuery.eq(Deliveries::getRiderId, riderId)
                .eq(Deliveries::getStatus, 2) // 已送达
                .ge(Deliveries::getDeliveredAt, todayStart);
        int todayCompleted = Math.toIntExact(deliveriesMapper.selectCount(todayCompletedQuery));
        statsVO.setTodayCompletedOrderCount(todayCompleted);

        // 获取本周数据（过去7天）
        LocalDateTime weekStart = LocalDateTime.now().minusDays(7);

        // 本周订单数
        LambdaQueryWrapper<Deliveries> weekOrdersQuery = new LambdaQueryWrapper<>();
        weekOrdersQuery.eq(Deliveries::getRiderId, riderId)
                .ge(Deliveries::getAssignedAt, weekStart);
        int weekOrders = Math.toIntExact(deliveriesMapper.selectCount(weekOrdersQuery));
        statsVO.setWeekOrderCount(weekOrders);

        // 获取本月数据（过去30天）
        LocalDateTime monthStart = LocalDateTime.now().minusDays(30);

        // 本月订单数
        LambdaQueryWrapper<Deliveries> monthOrdersQuery = new LambdaQueryWrapper<>();
        monthOrdersQuery.eq(Deliveries::getRiderId, riderId)
                .ge(Deliveries::getAssignedAt, monthStart);
        int monthOrders = Math.toIntExact(deliveriesMapper.selectCount(monthOrdersQuery));
        statsVO.setMonthOrderCount(monthOrders);

        // 获取总计数据

        // 总订单数
        LambdaQueryWrapper<Deliveries> totalOrdersQuery = new LambdaQueryWrapper<>();
        totalOrdersQuery.eq(Deliveries::getRiderId, riderId)
                .eq(Deliveries::getStatus, 2);
        int totalOrders = Math.toIntExact(deliveriesMapper.selectCount(totalOrdersQuery));
        statsVO.setTotalOrderCount(totalOrders);

        // 计算平均配送时间和准时率（复用相同地查询逻辑）
        try {
            LambdaQueryWrapper<Deliveries> avgTimeAndOnTimeQuery = new LambdaQueryWrapper<>();
            avgTimeAndOnTimeQuery.eq(Deliveries::getRiderId, riderId)
                    .eq(Deliveries::getStatus, 2) // 已送达
                    .ge(Deliveries::getDeliveredAt, monthStart)
                    .isNotNull(Deliveries::getPickedUpAt)
                    .isNotNull(Deliveries::getDeliveredAt)
                    .isNotNull(Deliveries::getEstimatedArrivalTime);

            List<Deliveries> completedDeliveries = deliveriesMapper.selectList(avgTimeAndOnTimeQuery);

            if (!completedDeliveries.isEmpty()) {
                // 计算平均配送时间
                long totalMinutes = 0;
                for (Deliveries delivery : completedDeliveries) {
                    long minutes = ChronoUnit.MINUTES.between(delivery.getPickedUpAt(), delivery.getDeliveredAt());
                    totalMinutes += minutes;
                }
                int avgMinutes = (int) (totalMinutes / completedDeliveries.size());
                statsVO.setAvgDeliveryTime(avgMinutes);

                // 计算准时率
                BigDecimal onTimeRate = getBigDecimal(completedDeliveries);
                statsVO.setOnTimeRate(onTimeRate);
            } else {
                statsVO.setAvgDeliveryTime(0);
                statsVO.setOnTimeRate(BigDecimal.ZERO);
            }
        } catch (Exception e) {
            log.error("计算平均配送时间或准时率出错: {}", e.getMessage(), e);
            statsVO.setAvgDeliveryTime(0);
            statsVO.setOnTimeRate(BigDecimal.ZERO);
        }

        return statsVO;
    }

    private BigDecimal getBigDecimal(List<Deliveries> deliveriesWithETA) {
        long onTimeCount = deliveriesWithETA.stream()
                .filter(d -> !d.getDeliveredAt().isAfter(d.getEstimatedArrivalTime()))
                .count();
        return new BigDecimal(onTimeCount)
                .divide(new BigDecimal(deliveriesWithETA.size()), 4, RoundingMode.HALF_UP);
    }

    @Override
    public PageResult<RiderVO> getRiderList(int page, int pageSize, String name, String phone) {
        log.info("查询骑手列表: page={}, pageSize={}, name={}, phone={}", page, pageSize, name, phone);

        // 构建查询条件
        LambdaQueryWrapper<Riders> queryWrapper = new LambdaQueryWrapper<>();

        // 添加姓名和电话筛选条件（如果有）
        if (name != null && !name.isEmpty()) {
            queryWrapper.like(Riders::getName, name);
        }

        if (phone != null && !phone.isEmpty()) {
            queryWrapper.like(Riders::getPhone, phone);
        }

        // 按创建时间降序排序
        queryWrapper.orderByDesc(Riders::getCreatedAt);

        // 分页查询
        Page<Riders> pageResult = new Page<>(page, pageSize);
        Page<Riders> ridersPage = baseMapper.selectPage(pageResult, queryWrapper);

        // 转换为VO对象
        List<RiderVO> riderVOList = new ArrayList<>();
        for (Riders rider : ridersPage.getRecords()) {
            RiderVO riderVO = c(rider);
            // 查询当前正在配送的订单数
            LambdaQueryWrapper<Deliveries> deliveryQuery = new LambdaQueryWrapper<>();
            deliveryQuery.eq(Deliveries::getRiderId, rider.getId())
                    .in(Deliveries::getStatus, Arrays.asList(0, 1)); // 待接单或配送中
            int currentOrderCount = Math.toIntExact(deliveriesMapper.selectCount(deliveryQuery));
            riderVO.setCurrentOrderCount(currentOrderCount);

            // 查询今日已完成订单数
            LocalDateTime todayStart = LocalDateTime.now().toLocalDate().atStartOfDay();
            LambdaQueryWrapper<Deliveries> completedQuery = new LambdaQueryWrapper<>();
            completedQuery.eq(Deliveries::getRiderId, rider.getId())
                    .eq(Deliveries::getStatus, 2) // 已送达
                    .ge(Deliveries::getDeliveredAt, todayStart);
            int completedOrderCount = Math.toIntExact(deliveriesMapper.selectCount(completedQuery));
            riderVO.setCompletedOrderCount(completedOrderCount);

            riderVOList.add(riderVO);
        }

        // 返回分页结果
        return new PageResult<RiderVO>().setTotal(ridersPage.getTotal()).setItems(riderVOList);
    }

    @Override
    public Integer getAvailableRider(Integer storeId) {
        log.info("获取可用骑手: storeId={}", storeId);

        // 1. 查询可用骑手（状态为可用且未达到10单上限的骑手）
        List<Riders> availableRiders = getAvailableRiders();

        if (availableRiders.isEmpty()) {
            log.warn("没有可用骑手");
            return null;
        }

        // 2. 简单分配算法：选择订单数量最少的骑手
        Riders selectedRider = b(availableRiders);

        log.info("选择骑手成功: riderId={}", selectedRider.getId());
        return selectedRider.getId();
    }

    private Riders b(List<Riders> availableRiders) {
        Riders selectedRider = availableRiders.get(0);
        int minOrderCount = Integer.MAX_VALUE;

        for (Riders rider : availableRiders) {
            LambdaQueryWrapper<Deliveries> countQuery = new LambdaQueryWrapper<>();
            countQuery.eq(Deliveries::getRiderId, rider.getId())
                    .in(Deliveries::getStatus, Arrays.asList(0, 1)); // 待接单或配送中

            long orderCount = deliveriesMapper.selectCount(countQuery);

            if (orderCount < minOrderCount) {
                minOrderCount = (int) orderCount;
                selectedRider = rider;
            }
        }

        // 3. 更新骑手状态（如果分配后达到10单，则设为忙碌）
        LambdaQueryWrapper<Deliveries> countQuery = new LambdaQueryWrapper<>();
        countQuery.eq(Deliveries::getRiderId, selectedRider.getId())
                .in(Deliveries::getStatus, Arrays.asList(0, 1)); // 待接单或配送中

        long currentOrderCount = deliveriesMapper.selectCount(countQuery);

        // 分配此订单后，如果总数达到10单，则设置为忙碌
        if (currentOrderCount + 1 >= 10) {
            selectedRider.setStatus(2); // 忙碌
            baseMapper.updateById(selectedRider);
        } else if (selectedRider.getStatus() != 1) {
            // 如果当前不是可用状态，但订单数未达到10，则设为可用
            selectedRider.setStatus(1); // 可用
            baseMapper.updateById(selectedRider);
        }
        return selectedRider;
    }

    private RiderVO c(Riders rider) {
        RiderVO riderVO = new RiderVO();
        BeanUtils.copyProperties(rider, riderVO);

        // 设置状态文本
        switch (rider.getStatus()) {
            case 0:
                riderVO.setStatusText("离线");
                break;
            case 1:
                riderVO.setStatusText("在线空闲");
                break;
            case 2:
                riderVO.setStatusText("配送中");
                break;
            default:
                riderVO.setStatusText("未知");
        }
        return riderVO;
    }
}
